# pushed_join.inc
#
# SUMMARY
#
#    Run the $push_query and verify it's push properties
#    according to the given arguments by looking at the handler
#    status variables and examining the EXPLAIN output.
#
# USAGE
#
#    let $push_query= <select statement>;
#    let $push_expected= <expected number of pushed joins>;
#    [let $push_message= <message>;]
#    --source pushed_join_check_pushed.inc
#
# PARAMETERS
#    $push_query=<select statement>
#      The select query to evaluate for pushed join
#
#    $push_expected=<number of pushed joins>
#     The expected number of pushed joins executed by query
#
#    $push_message=<message>
#      Expect the query to contain the given $message
#      in EXPLAIN or SHOW WARNINGS output
#
#

if (!$push_query)
{
  die Need $push_query as parameter to pushed_join_check_pushed.inc;
}

# Save ndb_pushed_* before query
let $defined_before =
  `select VARIABLE_VALUE from performance_schema.session_status
     where variable_name like 'ndb_pushed_queries_defined'`;
let $executed_before =
  `select VARIABLE_VALUE from performance_schema.session_status
     where variable_name like 'ndb_pushed_queries_executed'`;
let $dropped_before =
  `select VARIABLE_VALUE from performance_schema.session_status
     where variable_name like 'ndb_pushed_queries_dropped'`;
let $reads_before =
  `select VARIABLE_VALUE from performance_schema.session_status
     where variable_name like 'ndb_pushed_reads'`;

# Run the query
--disable_result_log ONCE
eval $push_query;

# Save ndb_pushed_* after query
let $defined_after =
  `select VARIABLE_VALUE from performance_schema.session_status
    where variable_name like 'ndb_pushed_queries_defined'`;
let $executed_after =
  `select VARIABLE_VALUE from performance_schema.session_status
    where variable_name like 'ndb_pushed_queries_executed'`;
let $dropped_after =
  `select VARIABLE_VALUE from performance_schema.session_status
    where variable_name like 'ndb_pushed_queries_dropped'`;
let $reads_after =
  `select VARIABLE_VALUE from performance_schema.session_status
    where variable_name like 'ndb_pushed_reads'`;

# Calculate number of pushed queries generated by the query
let $defined = `select $defined_after - $defined_before`;
let $executed = `select $executed_after - $executed_before`;
let $dropped = `select $dropped_after - $dropped_before`;
let $reads = `select $reads_after - $reads_before`;

#echo defined: $defined;
#echo executed: $executed;
#echo dropped: $dropped;
#echo reads: $reads;

#eval EXPLAIN $push_query;

if ($push_expected)
{
  #
  # The query is expected to be pushed, check that counters have
  # been incremented appropriately
  #

  # More than one pushed query must have been defined
  if (!$defined)
  {
    --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    --echo  - push_query: '$push_query'
    --echo  - defined: $defined
    --echo  - executed: $executed
    --echo  - dropped: $dropped
    --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    --die No pushed join defined for expected push!
  }

  # More than one pushed query must have been executed unless
  # dropped
  if (!$executed)
  {
    if (!$dropped)
    {
      --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      --echo  - push_query: '$push_query'
      --echo  - defined: $defined
      --echo  - executed: $executed
      --echo  - dropped: $dropped
      --echo  - reads: $reads
      --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
      --die No pushed join executed for expected push!
    }
  }


  if ($dropped)
  {
    # Print a message to log telling about the drop
    --echo Dropped $dropped pushed joins
  }

  # The number of reads should be greater then zero unless
  # all pushed joins where dropped
  if ($reads == 0)
  {
     # No reads (although queries was defined and executed)

     # Allow zero read when all defined queries have been dropped
     if ($defined != $dropped)
     {
       --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       --echo  - push_query: '$push_query'
       --echo  - defined: $defined
       --echo  - executed: $executed
       --echo  - dropped: $dropped
       --echo  - reads: $reads
       --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       --die No pushed reads although join was pushed!
     }

     # Print a message to log telling about this condition
     --echo No pushed reads since all defined were dropped
  }
}


if (!$push_expected)
{
  #
  # The query is expected to not be pushed, check that counters have
  # been incremented appropriately
  #

  if ($defined)
  {
    # There was a pushed join defined
    --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    --echo  - push_query: '$push_query'
    --echo  - defined: $defined
    --echo  - executed: $executed
    --echo  - dropped: $dropped
    --echo  - reads: $reads
    --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    --die Found defined pushes when push down was not expected!
  }

  # There should not be any executed when none defined
  if ($executed)
  {
    # There was a pushed join executed
    --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    --echo  - push_query: '$push_query'
    --echo  - defined: $defined
    --echo  - executed: $executed
    --echo  - dropped: $dropped
    --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    --die Found executed pushes when push down was not expected!
  }

  # There should not be any dropped when none defined
  if ($executed)
  {
    # There was a pushed join dropped
    --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    --echo  - push_query: '$push_query'
    --echo  - defined: $defined
    --echo  - executed: $executed
    --echo  - dropped: $dropped
    --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    --die Found dropped pushes when push down was not expected!
  }

  # There should not be any reads when none defined
  if ($reads)
  {
    # There was pushed join reads
    --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    --echo  - push_query: '$push_query'
    --echo  - defined: $defined
    --echo  - executed: $executed
    --echo  - dropped: $dropped
    --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    --die Found pushed reads when push down was not expected!
  }
}

if ($push_message)
{
  #
  # Check that EXPLAIN or the warnings contains the expected message
  # - dump the EXPLAIN to a file and load it back into a table
  #   which then is queried with a REGEXP
  #
  --disable_query_log
  CREATE TEMPORARY TABLE messages(txt varchar(1024));

  # Dump EXPLAIN to file
  let $dump_file = $MYSQLTEST_VARDIR/tmp/explain.txt;
  --output $dump_file
  eval EXPLAIN FORMAT=TRADITIONAL $push_query;

  eval LOAD DATA INFILE '$dump_file' INTO TABLE messages
         FIELDS TERMINATED BY '\n';
  --remove_file $dump_file

  #SELECT * FROM messages;

  # check if $message contains the expected message
  if (!`SELECT count(txt) FROM messages WHERE txt REGEXP $push_message`)
  {
  --echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  --echo Could not find expected message in EXPLAIN or SHOW WARNINGS!
  --echo  - expected: $push_message
  --echo  - found:
  SELECT * FROM messages;
  --die Did not find expected push message in EXPLAIN
  }
  DROP TABLE messages;
  --enable_query_log

  --echo Expected push message found in EXPLAIN;
}
# Add empty new line
--echo

# Reset the argument variables to detect missing assignment
let $push_query=;
let $push_expected=;
let $push_message=;

